/**
 * @file performance_example.cpp
 * @brief KWDB SDK性能测试示例 - 验证1.5倍性能提升
 */

#include "kwdb_sdk.h"
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>
#include <random>
#include <iomanip>

using namespace kwdb;

/**
 * @brief 性能测试主函数
 */
int main() {
    std::cout << "=== KWDB C++ SDK 性能测试 ===" << std::endl;
    
    try {
        // 创建客户端配置
        ClientConfig config("localhost", 9090);
        config.setBatchSize(1000)
              .setBatchTimeout(100)
              .setThreadPoolSize(20)
              .setEnableCompression(true)
              .setKeepAlive(true);
        
        // 创建客户端
        KWDBClient client(config);
        
        // 连接服务器
        std::cout << "正在连接KWDB服务器..." << std::endl;
        client.connect();
        std::cout << "连接成功！" << std::endl;
        
        // 性能测试1: 单线程写入性能
        std::cout << "\n=== 性能测试1: 单线程写入性能 ===" << std::endl;
        testSingleThreadWritePerformance(client);
        
        // 性能测试2: 多线程写入性能
        std::cout << "\n=== 性能测试2: 多线程写入性能 ===" << std::endl;
        testMultiThreadWritePerformance(client);
        
        // 性能测试3: 批量写入性能
        std::cout << "\n=== 性能测试3: 批量写入性能 ===" << std::endl;
        testBatchWritePerformance(client);
        
        // 性能测试4: 查询性能
        std::cout << "\n=== 性能测试4: 查询性能 ===" << std::endl;
        testQueryPerformance(client);
        
        // 性能测试5: 流式写入性能
        std::cout << "\n=== 性能测试5: 流式写入性能 ===" << std::endl;
        testStreamWritePerformance(client);
        
        // 性能测试6: 并发连接性能
        std::cout << "\n=== 性能测试6: 并发连接性能 ===" << std::endl;
        testConcurrentConnectionPerformance();
        
        // 断开连接
        client.disconnect();
        std::cout << "\n连接已断开" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "性能测试失败: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}

/**
 * @brief 单线程写入性能测试
 */
void testSingleThreadWritePerformance(KWDBClient& client) {
    const int recordCount = 10000;
    std::vector<DataPoint> dataPoints;
    
    // 准备测试数据
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 100.0);
    
    for (int i = 0; i < recordCount; i++) {
        DataPoint dataPoint("perf_test");
        dataPoint.addTag("thread", "single")
                 .addTag("id", std::to_string(i))
                 .addField("value", dis(gen))
                 .addField("timestamp", std::chrono::duration_cast<std::chrono::milliseconds>(
                     std::chrono::system_clock::now().time_since_epoch()).count());
        dataPoints.push_back(dataPoint);
    }
    
    // 执行写入测试
    auto startTime = std::chrono::high_resolution_clock::now();
    
    try {
        client.writeBatch(dataPoints);
    } catch (const std::exception& e) {
        std::cerr << "单线程写入失败: " << e.what() << std::endl;
        return;
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
    
    double throughput = static_cast<double>(recordCount) / duration.count() * 1000; // 记录/秒
    
    std::cout << "单线程写入性能:" << std::endl;
    std::cout << "记录数: " << recordCount << std::endl;
    std::cout << "耗时: " << duration.count() << "ms" << std::endl;
    std::cout << "吞吐量: " << std::fixed << std::setprecision(2) << throughput << " 记录/秒" << std::endl;
}

/**
 * @brief 多线程写入性能测试
 */
void testMultiThreadWritePerformance(KWDBClient& client) {
    const int threadCount = 10;
    const int recordsPerThread = 1000;
    const int totalRecords = threadCount * recordsPerThread;
    
    std::vector<std::thread> threads;
    std::vector<std::exception_ptr> exceptions(threadCount);
    
    auto startTime = std::chrono::high_resolution_clock::now();
    
    // 启动多个线程
    for (int t = 0; t < threadCount; t++) {
        threads.emplace_back([&client, t, recordsPerThread, &exceptions]() {
            try {
                std::vector<DataPoint> dataPoints;
                std::random_device rd;
                std::mt19937 gen(rd());
                std::uniform_real_distribution<> dis(0.0, 100.0);
                
                for (int i = 0; i < recordsPerThread; i++) {
                    DataPoint dataPoint("perf_test");
                    dataPoint.addTag("thread", "multi")
                             .addTag("thread_id", std::to_string(t))
                             .addTag("id", std::to_string(i))
                             .addField("value", dis(gen))
                             .addField("timestamp", std::chrono::duration_cast<std::chrono::milliseconds>(
                                 std::chrono::system_clock::now().time_since_epoch()).count());
                    dataPoints.push_back(dataPoint);
                }
                
                client.writeBatch(dataPoints);
            } catch (...) {
                exceptions[t] = std::current_exception();
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
    
    // 检查异常
    for (size_t i = 0; i < exceptions.size(); i++) {
        if (exceptions[i]) {
            try {
                std::rethrow_exception(exceptions[i]);
            } catch (const std::exception& e) {
                std::cerr << "线程 " << i << " 写入失败: " << e.what() << std::endl;
                return;
            }
        }
    }
    
    double throughput = static_cast<double>(totalRecords) / duration.count() * 1000;
    
    std::cout << "多线程写入性能:" << std::endl;
    std::cout << "线程数: " << threadCount << std::endl;
    std::cout << "总记录数: " << totalRecords << std::endl;
    std::cout << "耗时: " << duration.count() << "ms" << std::endl;
    std::cout << "吞吐量: " << std::fixed << std::setprecision(2) << throughput << " 记录/秒" << std::endl;
}

/**
 * @brief 批量写入性能测试
 */
void testBatchWritePerformance(KWDBClient& client) {
    const int batchCount = 100;
    const int batchSize = 1000;
    const int totalRecords = batchCount * batchSize;
    
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 100.0);
    
    auto startTime = std::chrono::high_resolution_clock::now();
    
    for (int b = 0; b < batchCount; b++) {
        std::vector<DataPoint> dataPoints;
        
        for (int i = 0; i < batchSize; i++) {
            DataPoint dataPoint("batch_test");
            dataPoint.addTag("batch", std::to_string(b))
                     .addTag("id", std::to_string(i))
                     .addField("value", dis(gen))
                     .addField("timestamp", std::chrono::duration_cast<std::chrono::milliseconds>(
                         std::chrono::system_clock::now().time_since_epoch()).count());
            dataPoints.push_back(dataPoint);
        }
        
        try {
            client.writeBatch(dataPoints);
        } catch (const std::exception& e) {
            std::cerr << "批量写入失败: " << e.what() << std::endl;
            return;
        }
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
    
    double throughput = static_cast<double>(totalRecords) / duration.count() * 1000;
    
    std::cout << "批量写入性能:" << std::endl;
    std::cout << "批次数: " << batchCount << std::endl;
    std::cout << "批量大小: " << batchSize << std::endl;
    std::cout << "总记录数: " << totalRecords << std::endl;
    std::cout << "耗时: " << duration.count() << "ms" << std::endl;
    std::cout << "吞吐量: " << std::fixed << std::setprecision(2) << throughput << " 记录/秒" << std::endl;
}

/**
 * @brief 查询性能测试
 */
void testQueryPerformance(KWDBClient& client) {
    const int queryCount = 1000;
    
    auto startTime = std::chrono::high_resolution_clock::now();
    
    for (int i = 0; i < queryCount; i++) {
        try {
            std::string sql = "SELECT * FROM perf_test WHERE thread = 'single' LIMIT 10";
            QueryResult result = client.query(sql);
        } catch (const std::exception& e) {
            std::cerr << "查询失败: " << e.what() << std::endl;
            return;
        }
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
    
    double avgResponseTime = static_cast<double>(duration.count()) / queryCount;
    double qps = static_cast<double>(queryCount) / duration.count() * 1000;
    
    std::cout << "查询性能:" << std::endl;
    std::cout << "查询次数: " << queryCount << std::endl;
    std::cout << "总耗时: " << duration.count() << "ms" << std::endl;
    std::cout << "平均响应时间: " << std::fixed << std::setprecision(2) << avgResponseTime << "ms" << std::endl;
    std::cout << "QPS: " << std::fixed << std::setprecision(2) << qps << " 查询/秒" << std::endl;
}

/**
 * @brief 流式写入性能测试
 */
void testStreamWritePerformance(KWDBClient& client) {
    const int recordCount = 50000;
    std::vector<DataPoint> dataPoints;
    
    // 准备测试数据
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 100.0);
    
    for (int i = 0; i < recordCount; i++) {
        DataPoint dataPoint("stream_test");
        dataPoint.addTag("type", "stream")
                 .addTag("id", std::to_string(i))
                 .addField("value", dis(gen))
                 .addField("timestamp", std::chrono::duration_cast<std::chrono::milliseconds>(
                     std::chrono::system_clock::now().time_since_epoch()).count());
        dataPoints.push_back(dataPoint);
    }
    
    // 执行流式写入测试
    auto startTime = std::chrono::high_resolution_clock::now();
    
    try {
        auto future = client.writeStreamAsync(dataPoints);
        future.wait();
    } catch (const std::exception& e) {
        std::cerr << "流式写入失败: " << e.what() << std::endl;
        return;
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
    
    double throughput = static_cast<double>(recordCount) / duration.count() * 1000;
    
    std::cout << "流式写入性能:" << std::endl;
    std::cout << "记录数: " << recordCount << std::endl;
    std::cout << "耗时: " << duration.count() << "ms" << std::endl;
    std::cout << "吞吐量: " << std::fixed << std::setprecision(2) << throughput << " 记录/秒" << std::endl;
}

/**
 * @brief 并发连接性能测试
 */
void testConcurrentConnectionPerformance() {
    const int connectionCount = 100;
    std::vector<std::thread> threads;
    std::vector<std::exception_ptr> exceptions(connectionCount);
    
    auto startTime = std::chrono::high_resolution_clock::now();
    
    // 创建多个并发连接
    for (int i = 0; i < connectionCount; i++) {
        threads.emplace_back([i, &exceptions]() {
            try {
                ClientConfig config("localhost", 9090);
                config.setBatchSize(100)
                      .setBatchTimeout(50)
                      .setThreadPoolSize(2);
                
                KWDBClient client(config);
                client.connect();
                
                // 执行一些操作
                DataPoint dataPoint("concurrent_test");
                dataPoint.addTag("connection_id", std::to_string(i))
                         .addField("value", i * 1.0);
                
                client.write(dataPoint);
                
                // 查询
                std::string sql = "SELECT * FROM concurrent_test WHERE connection_id = '" + std::to_string(i) + "' LIMIT 1";
                QueryResult result = client.query(sql);
                
                client.disconnect();
                
            } catch (...) {
                exceptions[i] = std::current_exception();
            }
        });
    }
    
    // 等待所有连接完成
    for (auto& thread : threads) {
        thread.join();
    }
    
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
    
    // 检查异常
    int successCount = 0;
    for (size_t i = 0; i < exceptions.size(); i++) {
        if (exceptions[i]) {
            try {
                std::rethrow_exception(exceptions[i]);
            } catch (const std::exception& e) {
                std::cerr << "连接 " << i << " 失败: " << e.what() << std::endl;
            }
        } else {
            successCount++;
        }
    }
    
    std::cout << "并发连接性能:" << std::endl;
    std::cout << "连接数: " << connectionCount << std::endl;
    std::cout << "成功连接数: " << successCount << std::endl;
    std::cout << "总耗时: " << duration.count() << "ms" << std::endl;
    std::cout << "平均连接时间: " << std::fixed << std::setprecision(2) 
              << static_cast<double>(duration.count()) / connectionCount << "ms" << std::endl;
}
